-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ShellParams protocol #772
Add ShellParams protocol #772
Conversation
031fefb
to
eed9274
Compare
Hmm, either need to have the test runner not run this test. Or need to run it from a shell. |
The question of how to run tests that rely on the shell came up in #596 too (cc @timrobertsdev). I haven't looked into it myself and don't have a good answer for now. I think what you've done in this PR of putting it in a separate file under |
@@ -0,0 +1,60 @@ | |||
// ANCHOR: all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These ANCHOR
comments are just used by mdbook (see https://rust-osdev.github.io/uefi-rs/HEAD/how_to/protocols.html#walkthrough for example), so unless you are looking to add this example to the book, you can leave these out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be good to have a shell application example in the book.
However it would be more useful once the shell protocol is merged.
uefi/src/proto/shell_params.rs
Outdated
/// Get a Vec of the shell parameter arguments | ||
#[cfg(feature = "alloc")] | ||
#[must_use] | ||
pub fn get_args(&self) -> Vec<String> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than collecting into a Vec
here, could we return an iterator? That would allow it to work without alloc
, and if the user actually needs a Vec
they can call .collect()
on it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh that's a good idea!
Do you think it would be useful to add something like this as well?
/// Get a slice of the args, as Char16 pointers
pub fn get_args_slice(&self) -> &[*const Char16] {
unsafe { from_raw_parts(self.argv, self.argc) }
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest not exposing that as pub fn
unless we have a specific real-world need for the API. Most of the uefi-rs API tries to provide safe wrappers rather than exposing raw pointers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about returning a slice or an iterator to CStr16
?
I couldn't figure out how to return a &[CStr16]
, not sure if that's possible.
But an Iterator<Item = CStr16>
would be doable. Or do you generally just want to return utf8 String
s only?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't figure out how to return a &[CStr16], not sure if that's possible.
Does this help?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm but can I turn a &[*const Char16]
into a &[CStr16]
?
Not without copying, right?
We've landed a change to the test-runner so that it runs under the UEFI shell. So you should be able to add runtime tests now :) |
Awesome! I'll try that, thanks! |
a9e69b3
to
fa9f26c
Compare
Added! :D As I understand, currently all tests are run by a single executable, For more testes I created an example PR: #922. Not sure if you like how I run the other tests. |
1c4e7b6
to
2247e23
Compare
uefi/src/proto/shell_params.rs
Outdated
pub fn get_args(&self) -> impl Iterator<Item = String> { | ||
unsafe { | ||
from_raw_parts( | ||
self.0.argv.cast::<*const data_types::chars::Char16>(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know why but the compiler thinks argv
is *const *const u16
instead of *const *const Char16
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type of Char16
is defined differently in uefi-raw
vs uefi
. uefi-raw
just uses a u16
so any value is accepted, whereas in uefi
we use the ucs2
crate that places some restrictions on the valid character values. (At some point I'd like to improve this situation, see #809 (comment) for more background.)
All of which is to say, this is expected :)
2247e23
to
cdbc0ef
Compare
#[derive(Debug)] | ||
#[repr(C)] | ||
pub struct ShellParametersProtocol { | ||
/// Pointer to a list of arguments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: period at ends of comments.
uefi/src/proto/shell_params.rs
Outdated
pub fn get_args(&self) -> impl Iterator<Item = String> { | ||
unsafe { | ||
from_raw_parts( | ||
self.0.argv.cast::<*const data_types::chars::Char16>(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type of Char16
is defined differently in uefi-raw
vs uefi
. uefi-raw
just uses a u16
so any value is accepted, whereas in uefi
we use the ucs2
crate that places some restrictions on the valid character values. (At some point I'd like to improve this situation, see #809 (comment) for more background.)
All of which is to say, this is expected :)
uefi/src/proto/shell_params.rs
Outdated
impl ShellParameters { | ||
/// Get an iterator of the shell parameter arguments | ||
#[cfg(feature = "alloc")] | ||
pub fn get_args(&self) -> impl Iterator<Item = String> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
naming nit: drop the get_
prefix on these methods (https://rust-lang.github.io/api-guidelines/naming.html#getter-names-follow-rust-convention-c-getter)
uefi/src/proto/shell_params.rs
Outdated
|
||
impl ShellParameters { | ||
/// Get an iterator of the shell parameter arguments | ||
#[cfg(feature = "alloc")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of our APIs return CStr16
s rather than converting to String. (Since there's a good chance that in real usage you'll pass these strings back into other uefi-rs methods, it makes sense to avoid the round-trip conversion from UCS-2 to UTF-8 and back). So this can change to:
pub fn args(&self) -> impl Iterator<Item = &CStr16> {
self.get_args_slice()
.iter()
.map(|x| unsafe { CStr16::from_ptr(*x) })
}
And doesn't need to be gated behind alloc
then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok sure, that's a good idea.
uefi/src/proto/shell_params.rs
Outdated
|
||
/// Get a slice of the args, as Char16 pointers | ||
#[must_use] | ||
pub fn get_args_slice(&self) -> &[*const Char16] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Along with changing the other method to be available without alloc
, I think we can drop the pub
from this method and keep it as an internal helper.
for arg in shell_params.get_args_slice() { | ||
let arg_str = unsafe { CStr16::from_ptr(*arg) }; | ||
info!(" '{}'", arg_str); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Since the result of getting the args is fully checked below, let's drop printing the args (many of our tests do print stuff, but it's only really necessary in cases where the output can ever change).
Useful to get the shell arguments for a commandline application. Signed-off-by: Daniel Schaefer <[email protected]>
Signed-off-by: Daniel Schaefer <[email protected]>
Signed-off-by: Daniel Schaefer <[email protected]>
cdbc0ef
to
2c9185b
Compare
Lgtm, thanks! |
Useful to get the shell arguments for a commandline application.
Running example application on UEFI shell:
Checklist